#include "Direction.h"

Direction Direction::MatchDirctionByRotation(glm::vec3 rotaion)
{
  Direction result;
  float x = glm::degrees(rotaion.x);
  const float k = 45.0f;
  if (x > -k * 2 && x < -k)
  {
    result = Direction::Down;
  }
  else if (x > k && x < k * 2)
  {
    result = Direction::Up;
  }
  else
  {
    result = MatchDirctionByRotationY(rotaion.y);
  }
  return result;
}

Direction Direction::MatchDirctionByRotationY(float y)
{
  Direction result;
  const float k = 45.0f;
  y = glm::degrees(y);
  if (y > k && y < k * 3)
  {
    result = Direction::West;
  }
  else if (y > k * 5 && y < k * 7)
  {
    result = Direction::East;
  }
  else if (y > k * 3 && y < k * 5)
  {
    result = Direction::South;
  }
  else
  {
    result = Direction::North;
  }
  return result;
}

Direction Direction::MatchDirctionByFacingNormal(glm::ivec3 normal)
{
  if (normal.x > 0)
    return Direction::Right;
  else if (normal.x < 0)
    return Direction::Left;
  else if (normal.y > 0)
    return Direction::Up;
  else if (normal.y < 0)
    return Direction::Down;
  else if (normal.z > 0)
    return Direction::Front;
  else
    return Direction::Back;
}

Direction Direction::GetOppsite() const
{
  if (m_dir % 2 == 0)
    return m_dir + 1;
  else
    return m_dir - 1;
}

std::string Direction::ToString() const
{
  switch (m_dir)
  {
  case Direction::West:
    return "West";
  case Direction::East:
    return "East";
  case Direction::Up:
    return "Up";
  case Direction::Down:
    return "Down";
  case Direction::South:
    return "South";
  case Direction::North:
    return "North";
  default:
    return "None";
  }
}

glm::vec3 Direction::GetDirectionVec(uint8_t dir)
{
  assert(dir < 6);

  constexpr static const std::array<glm::ivec3, 6> dirVec{{
      {1, 0, 0},  // x+
      {-1, 0, 0}, // x-
      {0, 1, 0},  // y+
      {0, -1, 0}, // y-
      {0, 0, 1},  // z+
      {0, 0, -1}, // z-
  }};

  return dirVec[dir];
}